﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;

using SdmxMl.Pdf;

using SdmxMl.Manager;
using SdmxMl.Structure;
using SdmxMl.Common;

namespace SdmxMl.Pdf
{
    public class PdfConceptSchemeGen : PdfArtefactGen
    {

        public PdfConceptSchemeGen(string docPath, SmManager smMgr, string artefactFullId, string lang)
            : base(docPath, smMgr, SdmxArtefactType.Concepts, artefactFullId, lang)
        {
            Dictionary<string, string> dicoAlphasort = new Dictionary<string, string>();
            dicoAlphasort.Add("en", "Alphabetical list of concepts");
            dicoAlphasort.Add("de", "Alphabetische Liste der Konzepte");
            dicoAlphasort.Add("fr", "Liste alphabétique des concepts");
            dicoAlphasort.Add("it", "Elenco alfabetico dei concetti");

            ConceptSchemeType cst = targetArtefact as ConceptSchemeType;

            try
            {
                // Concept Scheme info
                document.Add(new Paragraph("ConceptScheme: " + targetArtefact.FullIdent));
                document.Add(new Chunk(" "));
                document.Add(pdfVar.GetDetailArtefactTable(cst));
                document.Add(new Chunk(" "));

                // Alpha list
                string ptitle = dicoAlphasort.ContainsKey(lang) ? dicoAlphasort[lang] : dicoAlphasort["en"];
                document.Add(new Paragraph(ptitle));
                document.Add(new Chunk(" "));

                // list Concepts
                List<ConceptType> conceptList = new List<ConceptType>(cst.ConceptList.Count);
                foreach (ConceptType c in cst.ConceptList)
                    conceptList.Add(c);

                PdfPTable aTable = pdfVar.GenerateAlphaVarConcept(conceptList);
                document.Add(aTable);

                // Concept detail
                document.NewPage();
                document.Add(new Paragraph("Detail"));
                document.Add(new Paragraph(" "));
                int row = 0;
                HierarchyNode hn = ProduceHierarchy(cst);
                hn.Nodes.SortNodes();
                PutRecurseConcept(hn, ref row);
            }
            finally
            {
                document.Close();
            }
        }

        private void PutRecurseConcept(HierarchyNode hn, ref int row)
        {
            ConceptType c = hn.Tag as ConceptType;
            if (c != null)
                document.Add(pdfVar.GetDetailConceptTable(row++, c));

            foreach (HierarchyNode h in hn.Nodes)
                PutRecurseConcept(h, ref row);

        }


        private HierarchyNode ProduceHierarchy(ConceptSchemeType cst)
        {
            // Form tree hierarchy
            TreeNode root = new TreeNode("root");
            cst.FillNode(root);

            // Independant hierarchy
            HierarchyNode hnroot = new HierarchyNode(root.Nodes[0].Nodes[0].Text, 0);
            FillIndependant(root.Nodes[0].Nodes[0], hnroot);

            return hnroot.Nodes[0];
        }

        private void FillIndependant(TreeNode node, HierarchyNode hn)
        {
            HierarchyNode hnChild = new HierarchyNode(node.Text, node.ImageIndex);
            hnChild.Tag = node.Tag;
            hn.Nodes.Add(hnChild);

            foreach (TreeNode n in node.Nodes)
                FillIndependant(n, hnChild);

            if (hnChild.Nodes.Count > 1)
                hnChild.Nodes.SortNodes();
           
        }
    }
}
